﻿#include "TableInSceneWidget.h"
#include "ui_TableInSceneWidget.h"

#include <QFileDialog>
#include <QTextStream>
#include <QTextCodec>
#include <QMenu>
#include <QDebug>

#include "TableInSceneModel.h"
#include "GlobalDefine.h"
#include "ImportUtils.h"
#include "KSpinboxDeleget.h"

class TableInSceneWidget::TableInSceneWidgetPrivate :public QObject, public AstScene
{
public:
	QString label_name;
	QModelIndexList copy_list;
	KSpinboxDeleget* item_delegate;
public:
	TableInSceneWidgetPrivate(QObject*parent):QObject(parent)
	{
		item_delegate = nullptr;
	}
	virtual int type() override
	{
		return AstScene::SCENE_IN;
	}
	virtual QString typeName() override
	{
		return "TableInScene";
	}
	virtual QString label()
	{
		return label_name;
	}
	virtual void setLabel(const QString&s)
	{
		label_name = s;
	}
	virtual QWidget* widget() override
	{
		return qobject_cast<QWidget*>(parent());
	}
	virtual void onOpening() override
	{}
	virtual void onClosing() override
	{}
};

TableInSceneWidget::TableInSceneWidget(QWidget *parent)
	: QWidget(parent), private_ptr(new TableInSceneWidgetPrivate(this))
{
	ui = new Ui::TableInSceneWidget();
	ui->setupUi(this);

	initTable();
}

TableInSceneWidget::~TableInSceneWidget()
{
	delete ui;
}

void TableInSceneWidget::initTable()
{
	ui->tableView->setFont(font());
	TableInSceneModel*model = new TableInSceneModel(ui->tableView);
	
	model->setHeaderTitle(QString("A,B,C").split(","));
	//model->setColumnCount(model->COLUMN_MAX);

	ui->tableView->setModel(model);
	//ui->tableView->setItemDelegateForColumn(KCombinationModel::COLUMN_POLICYNAME, new PolicyColumnDelegate(this));
	//ui->tableView->setItemDelegateForColumn(KCombinationModel::COLUMN_CONTRACTINFO, new ContractInfoDelegate(this));
	//ui->tableView->setItemDelegateForColumn(KCombinationModel::COLUMN_Price, new ContractInfoDelegate(this));
	//ui->tableView->setItemDelegateForColumn(KCombinationModel::COLUMN_Bid, new ContractInfoDelegate(this));
	//ui->tableView->setItemDelegateForColumn(KCombinationModel::COLUMN_Ask, new ContractInfoDelegate(this));
	//ui->tableView->setItemDelegateForColumn(KCombinationModel::COLUMN_MaxMinPrice, new ContractInfoDelegate(this));
	//ui->tableView->setItemDelegateForColumn(KCombinationModel::COLUMN_Position, new ContractInfoDelegate(this));

	model->syncRows();

	ui->tableView->show();
	//ui->tableView->resizeColumnsToContents();
	ui->tableView->resizeRowsToContents();
	//ui->tableView->horizontalHeader()->setStyleSheet("QHeaderView::section{background:lightgray;color:block;}");
	//ui->tableView->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;color:block;}");

	// 启用右键菜单
	ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);

	connect(ui->tableView, &QTableView::customContextMenuRequested, this, &TableInSceneWidget::onTableContextMenu);
	//connect(ui->tableView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(onTableDblClicked(const QModelIndex &)));
	//connect(ui->tableView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(onTableCurrentChanged(const QModelIndex &, const QModelIndex &)));
	//connect(KGlobalData::instance(), &KGlobalData::sigNewTransaction, this, &KCombinationOrderWidget::slotNewTransaction);
	//ui->tableView->setItemDelegate();

	private_ptr->item_delegate = new KSpinboxDeleget(this);
	private_ptr->item_delegate->doublespin_decimals = 3;

	ui->tableView->setItemDelegate(private_ptr->item_delegate);
}

void TableInSceneWidget::onMenuSetCellToDouble()
{
	TableInSceneModel*model = (TableInSceneModel*)ui->tableView->model();
	QVector<QVariant>* row_ptr;// DataOfIdx(int idx)
	for (auto a : ui->tableView->selectionModel()->selectedIndexes()) {
		row_ptr = model->rowDataOfIdx(a.row());
		if (a.column() < row_ptr->length()) {
			QVariant v = row_ptr->operator[](a.column());
			row_ptr->operator[](a.column()).setValue(v.toDouble());
		}
	}
	update();
}
void TableInSceneWidget::onMenuSetCellToText()
{
	TableInSceneModel*model = (TableInSceneModel*)ui->tableView->model();
	QVector<QVariant>* row_ptr;// DataOfIdx(int idx)
	for (auto a : ui->tableView->selectionModel()->selectedIndexes()) {
		row_ptr = model->rowDataOfIdx(a.row());
		if (a.column() < row_ptr->length()) {
			QVariant v = row_ptr->operator[](a.column());
			row_ptr->operator[](a.column()).setValue(v.toString());
		}
	}
	update();
}
void TableInSceneWidget::onMenuSetCellToEmpty()
{
	TableInSceneModel*model = (TableInSceneModel*)ui->tableView->model();
	QVector<QVariant>* row_ptr;// DataOfIdx(int idx)
	for (auto a : ui->tableView->selectionModel()->selectedIndexes()) {
		row_ptr = model->rowDataOfIdx(a.row());
		if (a.column() < row_ptr->length()) {
			//QVariant v = row_ptr->operator[](a.column());
			row_ptr->operator[](a.column()).clear();
		}
	}
	update();
}
void TableInSceneWidget::onMenuCopyCells()
{
	private_ptr->copy_list = ui->tableView->selectionModel()->selectedIndexes();
}
static QModelIndex __minIndex(const QModelIndexList&l)
{
	QModelIndex idx;
	
	idx = *l.begin();
	for (auto a : l) {
		if (a.row() < idx.row() && a.column() < idx.column())
			idx = a;
	}
	return idx;
}
void TableInSceneWidget::onMenuPasteCells()
{
	QModelIndex src = __minIndex(private_ptr->copy_list);
	QModelIndex dst = __minIndex(ui->tableView->selectionModel()->selectedIndexes());

	if (src != dst) {
		int delta_row, delta_col;

		TableInSceneModel*model = (TableInSceneModel*)ui->tableView->model();
		QVector<QVariant>* src_row_ptr, *dst_row_ptr;// DataOfIdx(int idx)
		for (auto a : private_ptr->copy_list) {
			delta_row = a.row() - src.row();
			delta_col = a.column() - src.column();

			QModelIndex d = model->index(dst.row() + delta_row, dst.column() + delta_col);
			//if (d.column() < model->columnCount() && d.row() < model->rowCount())
			if (d.isValid())
				model->setData(d, model->data(a, Qt::EditRole));
		}
	}
	private_ptr->copy_list.clear();

	update();
}

void TableInSceneWidget::onTableContextMenu(const QPoint&pt)
{
	QMenu menu;
	QAction*act;
	//menu.addAction(QStringLiteral("设置为Double"), this, &TableInSceneWidget::onMenuSetCellToDouble);
	//menu.addAction(QStringLiteral("设置为文本"), this, &TableInSceneWidget::onMenuSetCellToText);
	menu.addAction(QStringLiteral("复制"), this, &TableInSceneWidget::onMenuCopyCells);
	act = menu.addAction(QStringLiteral("粘贴"), this, &TableInSceneWidget::onMenuPasteCells);
	act->setEnabled(!!private_ptr->copy_list.count());
	menu.addSeparator();
	menu.addAction(QStringLiteral("清空"), this, &TableInSceneWidget::onMenuSetCellToEmpty);
	menu.exec(cursor().pos());
}
void TableInSceneWidget::on_btn_import_clicked()
{
	ImportSetting is;
	
	QString filename = QFileDialog::getOpenFileName(this, QStringLiteral("选择文件"), ".", "*.csv;*.txt");

	QFileInfo fi(filename);

	if (!fi.isReadable()) {
		return;
	}

	int count = 0;
	QFile f(filename);
	if (!f.open(/*QIODevice::Text | */QIODevice::OpenModeFlag::ReadOnly)) {
		return;
	}

	QString code_name = is.codec_name;

	QTextCodec*code = nullptr;
	if (!code_name.isEmpty())
		code = QTextCodec::codecForName(code_name.toLocal8Bit());
	if (!code)
		code = QTextCodec::codecForLocale();

	QTextStream in(&f);
	in.setCodec(code);
	//QDataStream ds;

	TableInSceneModel*model = (TableInSceneModel*)ui->tableView->model();
	QVector<QVector<QVariant>>*model_data = model->modelData();
	model_data->clear();

	QString title;// = in.readLine();
	if (!in.readLineInto(&title))
		return;

	model->setHeaderTitle(title.split(','));

	QString line;
	while (in.readLineInto(&line)) {
		QVector<QVariant> a;
		ImportUtils::importRow(line, &a, ',');
		model_data->append(a);
	}
	model->syncRows();

}

AstScene* TableInSceneWidget::operator()()
{
	return dynamic_cast<AstScene*>(private_ptr); //qobject_cast<TextInScene*>(private_ptr);
}

TableInSceneModel*TableInSceneWidget::model()
{
	return dynamic_cast<TableInSceneModel*>(ui->tableView->model());
}

QTableView* TableInSceneWidget::tableView()
{
	return ui->tableView;
}
